package com.meichis.mcsappframework.http;

import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import com.meichis.mcsappframework.entity.Attachment;
import com.meichis.mcsappframework.http.DONERESULT.ERRORCODE;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class MCSWebDownLoadProvider {

	private static MCSWebDownLoadProvider _this;
	private static int TIME_OUT =20000;//设置超时20s
	private ExecutorService executorService = Executors.newFixedThreadPool(3); // 固定三个线程来执行任务
	private Handler UIHandler;
	private Attachment cancelAtt;//取消下载的文件
	private static final int MESSAGEWHAT_DOWNLOAD=1; //下载     执行MODCallback中的execute()方法；
	private static final int MESSAGEWHAT_DOWNLOAD_DOWNLOADING=2; //下载中    执行MODCallback中的onDownloadSize()方法  多次执行；
	public MCSWebDownLoadProvider() {
		if (UIHandler==null) {
			UIHandler = new Handler(){

				@Override
				public void handleMessage(Message msg) {
					ResultObject resultObject = (ResultObject) msg.obj;
					switch (msg.what) {
						case MESSAGEWHAT_DOWNLOAD:
							resultObject.callback.execute(resultObject.errcode, resultObject.pathName);
							break;
						case MESSAGEWHAT_DOWNLOAD_DOWNLOADING:
							resultObject.callback.onDownloadSize(resultObject.size);
							break;
						default:
							break;
					}
					super.handleMessage(msg);
				}

			};
		}
	}
	/**
	 * 构造单列MCSWebDownLoadProvider对象
	 * @return
	 */
	public static MCSWebDownLoadProvider getInstatince() {
		if (_this == null) {
			_this = new MCSWebDownLoadProvider();
		}

		return _this;
	}
	/**
	 * 下载文件
	 * @param dir 下载完成文件存放路径
	 * @param att 需要下载文件的信息
	 * @param callback 下载调用接口
	 */
	public void downLoadFile(final String dir, final Attachment att, final MODCallback callback){
		executorService.submit(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				String filename = att.getAttName() + "." +att.getExtName();//完整文件名
				ResultObject resultObject = new ResultObject();
				resultObject.callback = callback;
				HttpURLConnection conn = null;
				try {
					URL url = new URL(att.getAttUri());
					conn = (HttpURLConnection) url.openConnection();
//					conn.setDoInput(true);
					conn.setConnectTimeout(TIME_OUT);
					conn.setReadTimeout(TIME_OUT);
					conn.connect();

//					int length = conn.getContentLength();//非Chunk传输，且由于是int型，文件最大超越int最大值会返回-1
					long length;
					//获取文件大小
//					if (Build.VERSION.SDK_INT >= 24) {
//						length = conn.getContentLengthLong();
//					}else{
//						length = getContentSize(conn);
//					}
					length = att.getFileSize();
//					att.setFileSize(length);
					File filepath = new File(dir);
					if (!filepath.exists()) {
						filepath.mkdirs();
					}
					InputStream is = conn.getInputStream();
					FileOutputStream fileOutputStream = null;
					if (is!=null){
						File file = new File(dir,filename);
						fileOutputStream = new FileOutputStream(file,false);
						byte[] buf = new byte[1024];
						int ch =-1;
						long count = 0;
						int updateCount = 0;
						while ((ch=is.read(buf))!=-1){
							if (att == cancelAtt) {//此文件已被取消下载
								try {
									is.close();
									fileOutputStream.close();
									conn.disconnect();
									file.deleteOnExit();
								} catch (Exception e) {
									fileOutputStream.close();
								}finally{
									resultObject.errcode = ERRORCODE.CANCEL;
									Message toUI = UIHandler.obtainMessage();
									toUI.what = MESSAGEWHAT_DOWNLOAD;
									toUI.obj = resultObject;
									UIHandler.sendMessage(toUI);
								}
								return;
							}
							fileOutputStream.write(buf, 0, ch);
							count += ch;
							if ((length == -1 || length > 0) && (updateCount == 0 || count * 100 / length - 2 >= updateCount)) {
								updateCount += 2;
								resultObject.size = length == -1 ? -1 : updateCount;//已下载的百分比
								Message toUI = UIHandler.obtainMessage();
								toUI.obj = resultObject;
								toUI.what = MESSAGEWHAT_DOWNLOAD_DOWNLOADING;
								UIHandler.sendMessage(toUI);
							}
						}
						fileOutputStream.flush();
						if (fileOutputStream != null) {
							fileOutputStream.close();
							resultObject.errcode = ERRORCODE.SUCCESS;
							resultObject.pathName = file.getPath();//下载完成存放路径
							Message toUI = UIHandler.obtainMessage();
							toUI.obj = resultObject;
							toUI.what = MESSAGEWHAT_DOWNLOAD;
							UIHandler.sendMessage(toUI);
						}
					} else { //输入流为空
						Message toUI = UIHandler.obtainMessage();
						resultObject.errcode = ERRORCODE.FAILED;
						toUI.obj = resultObject;
						toUI.what = MESSAGEWHAT_DOWNLOAD;
						UIHandler.sendMessage(toUI);
					}
				} catch (Exception e) {
					e.printStackTrace();
					Message toUI = UIHandler.obtainMessage();
					resultObject.errcode = ERRORCODE.FAILED;
					toUI.obj = resultObject;
					toUI.what = MESSAGEWHAT_DOWNLOAD;
					UIHandler.sendMessage(toUI);
				} finally {
					if (conn != null) {
						conn.disconnect();
					}
				}
			}
		});
	}
	/**
	 * 取消下载文件
	 * @param att
	 */
	public void cancelDownFile(Attachment att) {
		cancelAtt = att;
	}
	/**
	 * 下载过程中作为Message.obj 对象
	 * @author Administrator
	 *
	 */
	public class ResultObject{
		MODCallback callback; //完成下载后接口
		ERRORCODE errcode; //当前状态
		int size;  //已下载百分比
		String pathName; //文件路径
	}
	/**
	 * 下载完成之后调用
	 * @author Administrator
	 *
	 */
	public interface MODCallback {

		public void execute(ERRORCODE errcode, Object pathName);
		public void onDownloadSize(int size);
	}

	/**
	 * android7.0 以下获取size 规则
	 * @param conn
	 * @return contentSize
	 */
	private long getContentSize(HttpURLConnection conn) {
		long contentSize = -1;
		if (conn == null) {
			return contentSize;
		}
		String contentLength = conn.getHeaderField("Content-Length");
		if (contentLength != null && !TextUtils.isEmpty(contentLength)) {
			try {
				contentSize = Long.parseLong(contentLength);
			}catch (NumberFormatException e){
				e.printStackTrace();
			}
		}
		return contentSize;
	}
}
